import { createStore, Commit } from 'vuex';
import request from './utils/request';

export interface ResponseType<T = Record<string, never>> {
  code: number;
  msg: string;
  data: T;
}

export interface UserProps {
  isLogin: boolean;
  nickName?: string;
  _id?: string;
  column?: string;
  email?: string;
  description?: string;
  avatar?: ImageProps;
}

export interface ImageProps {
  _id?: string;
  url?: string;
  createdAt?: string;
}

export interface ColumnProps {
  _id: string;
  title: string;
  avatar?: ImageProps;
  description: string;
}

export interface PostProps {
  _id?: string;
  title: string;
  excerpt?: string;
  content?: string;
  image?: ImageProps | string;
  createdAt?: string;
  column: string;
  author?: string | UserProps;
}

export interface GlobalErrorProps {
  status: boolean;
  message?: string;
}

export interface GlobalDataProps {
  error: GlobalErrorProps;
  token: string;
  loading: boolean;
  columns: ColumnProps[];
  posts: PostProps[];
  user: UserProps;
}

const getAndCommit = async (url: string, mutationName: string, commit: Commit) => {
  const { data } = await request.get(url);
  commit(mutationName, data);
};

const postAndCommit = async (url: string, mutationName: string, commit: Commit, payload: any) => {
  const { data } = await request.post(url, payload);
  mutationName && commit(mutationName, data);
  return data;
};

export default createStore<GlobalDataProps>({
  state: {
    error: { status: false },
    token: localStorage.getItem('token') || '',
    loading: false,
    columns: [],
    posts: [],
    user: { isLogin: false },
  },
  mutations: {
    createPost(state, newPost) {
      state.posts.push(newPost);
    },
    fetchColumns(state, rawData) {
      state.columns = rawData.data.list;
    },
    fetchColumn(state, rawData) {
      state.columns = [rawData.data];
    },
    fetchPosts(state, rawData) {
      state.posts = rawData.data.list;
    },
    setLoading(state, status) {
      state.loading = status;
    },
    setError(state, e: GlobalErrorProps) {
      state.error = e;
    },
    fetchCurrentUser(state, rawData) {
      state.user = { isLogin: true, ...rawData.data };
    },
    login(state, rawData) {
      const { token } = rawData.data;
      state.token = token;
      localStorage.setItem('token', token);
      request.defaults.headers.common.Authorization = `Bearer ${token}`;
    },
    logout(state) {
      state.token = '';
      state.user = { isLogin: false };
      localStorage.remove('token');
      delete request.defaults.headers.common.Authorization;
    },
  },
  actions: {
    // 获取首页的所有专栏
    fetchColumns({ commit }) {
      getAndCommit('/columns', 'fetchColumns', commit);
    },
    // 获取具体的某个专栏信息
    fetchColumn({ commit }, cid) {
      getAndCommit(`/columns/${cid}`, 'fetchColumn', commit);
    },
    // 获取某个专栏下面的文章列表
    fetchPosts({ commit }, cid) {
      getAndCommit(`/columns/${cid}/posts`, 'fetchPosts', commit);
    },
    fetchCurrentUser({ commit }) {
      getAndCommit('user/current', 'fetchCurrentUser', commit);
    },
    login({ commit }, payload) {
      return postAndCommit('user/login', 'login', commit, payload);
    },
    singup({ commit }, payload) {
      return postAndCommit('/users', '', commit, payload);
    },
    createPost({ commit }, payload) {
      return postAndCommit('/posts', 'createPost', commit, payload);
    },
    loginAndFetch({ dispatch }, loginData) {
      return dispatch('login', loginData).then(() => {
        return dispatch('fetchCurrentUser');
      });
    },
  },
  getters: {
    getColumnById: state => (id: string) => {
      console.log(state.columns.find(c => c._id === id));
      return state.columns.find(c => c._id === id);
    },
    getPostsByCid: state => (cid: string) => {
      return state.posts
        .filter(post => post.column === cid)
        .map(post => {
          if (!post.image) {
            post.image = {
              url: require('assets/column.jpg'),
            };
          }
          return post;
        });
    },
  },
  modules: {},
});
